// 安装依赖: npm install ws
const WebSocket = require("ws");
const http = require("http");
const server = http.createServer();
const wss = new WebSocket.Server({ server });

// 存储连接的用户和房间信息
const users = new Map(); // key: WebSocket, value: { username, room }
const rooms = {
  general: new Set(), // 公共大厅
  tech: new Set(), // 技术讨论
  random: new Set(), // 闲聊
};

// 广播消息到房间内的所有用户
function broadcastToRoom(room, message, sender = null) {
  const stringifiedMessage = JSON.stringify(message);

  rooms[room].forEach((client) => {
    if (client.readyState === WebSocket.OPEN && client !== sender) {
      client.send(stringifiedMessage);
    }
  });
}

// 向特定客户端发送消息
function sendToClient(client, message) {
  if (client.readyState === WebSocket.OPEN) {
    client.send(JSON.stringify(message));
  }
}

// 获取房间内的所有用户名
function getRoomUserNames(room) {
  return Array.from(rooms[room]).map((client) => {
    const user = users.get(client);
    return user ? user.username : "未知用户";
  });
}

// 处理WebSocket连接
wss.on("connection", (ws) => {
  console.log("新客户端连接");

  // 处理收到的消息
  ws.on("message", (data) => {
    try {
      const message = JSON.parse(data);

      switch (message.type) {
        case "login":
          // 存储用户信息
          users.set(ws, {
            username: message.username,
            room: null,
          });

          // 通知用户登录成功
          sendToClient(ws, {
            type: "system",
            content: `登录成功，欢迎 ${message.username}！`,
          });

          console.log(`${message.username} 已登录`);
          break;

        case "joinRoom":
          const user = users.get(ws);
          if (!user) return;

          // 如果之前在其他房间，先离开
          if (user.room && rooms[user.room]) {
            rooms[user.room].delete(ws);
            broadcastToRoom(user.room, {
              type: "system",
              content: `${user.username} 已离开房间`,
            });
            // 更新房间用户列表
            broadcastToRoom(user.room, {
              type: "userList",
              users: getRoomUserNames(user.room),
            });
          }

          // 加入新房间 - 修复了此处的赋值错误
          const newRoom = message.room;
          if (rooms[newRoom]) {
            user.room = newRoom;
            rooms[newRoom].add(ws); // 修复了原代码中的赋值错误

            // 通知用户已加入房间
            sendToClient(ws, {
              type: "roomChange",
              room: newRoom,
            });

            // 通知房间内其他用户
            broadcastToRoom(
              newRoom,
              {
                type: "system",
                content: `${user.username} 已加入房间`,
              },
              ws
            );

            // 更新房间用户列表
            broadcastToRoom(newRoom, {
              type: "userList",
              users: getRoomUserNames(newRoom),
            });

            console.log(`${user.username} 已加入房间 ${newRoom}`);
          }
          break;

        case "chat":
          const chatUser = users.get(ws);
          if (!chatUser || !chatUser.room) return;

          // 广播聊天消息到房间内的所有用户
          const chatMessage = {
            type: "chat",
            username: chatUser.username,
            content: message.content,
            timestamp: message.timestamp,
          };

          // 发送给发送者自己
          sendToClient(ws, chatMessage);

          // 广播给房间内其他用户
          broadcastToRoom(chatUser.room, chatMessage, ws);

          console.log(
            `[${chatUser.room}] ${chatUser.username}: ${message.content}`
          );
          break;

        case "logout":
          const logoutUser = users.get(ws);
          if (logoutUser) {
            console.log(`${logoutUser.username} 已登出`);

            // 如果在房间内，离开房间
            if (logoutUser.room && rooms[logoutUser.room]) {
              rooms[logoutUser.room].delete(ws);
              broadcastToRoom(logoutUser.room, {
                type: "system",
                content: `${logoutUser.username} 已离开房间`,
              });
              // 更新房间用户列表
              broadcastToRoom(logoutUser.room, {
                type: "userList",
                users: getRoomUserNames(logoutUser.room),
              });
            }

            users.delete(ws);
          }
          break;
      }
    } catch (error) {
      console.error("消息处理错误:", error);
    }
  });

  // 处理连接关闭
  ws.on("close", () => {
    const user = users.get(ws);
    if (user) {
      console.log(`${user.username} 已断开连接`);

      // 如果在房间内，移除用户并通知
      if (user.room && rooms[user.room]) {
        rooms[user.room].delete(ws);
        broadcastToRoom(user.room, {
          type: "system",
          content: `${user.username} 已离开房间`,
        });
        // 更新房间用户列表
        broadcastToRoom(user.room, {
          type: "userList",
          users: getRoomUserNames(user.room),
        });
      }

      users.delete(ws);
    } else {
      console.log("未知用户已断开连接");
    }
  });

  // 处理错误
  ws.on("error", (error) => {
    console.error("WebSocket错误:", error);
  });
});

// 启动服务器
const PORT = 8080;
server.listen(PORT, () => {
  console.log(`WebSocket服务器已启动，监听端口 ${PORT}`);
});
